package com.alisls.demo.springcloud.service.user.service.impl.resource;

import com.alisls.demo.springcloud.common.core.exception.BizException;
import com.alisls.demo.springcloud.common.core.util.IdWorker;
import com.alisls.demo.springcloud.service.user.dao.menu.MenuDAO;
import com.alisls.demo.springcloud.service.user.dto.resource.MenuDTO;
import com.alisls.demo.springcloud.service.user.entity.resource.MenuDO;
import com.alisls.demo.springcloud.service.user.service.resource.MenuService;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;

/**
 * 菜单服务
 *
 * @author Ke Wang
 * @date 2020/11/5
 */
@Service("menuService")
public class MenuServiceImpl implements MenuService {

    @Resource
    private IdWorker idWorker;

    @Resource
    private MenuDAO menuDAO;

    /**
     * 根据菜单编码查询菜单
     * @param code
     * @return
     */
    @Override
    public MenuDTO getByCode(String code) {
        return null;
    }

    /**
     * 保存菜单，同时将菜单数据保存在Redis中，用menuCode作为Key
     * @param menuDTO
     * @return
     * @throws BizException
     */
    @CachePut(cacheNames = "sys_menu", key = "#menuDTO.code")
    @Override
    public MenuDTO save(MenuDTO menuDTO) throws BizException {
        if (menuDTO == null) {
            return null;
        }
        // 生成ID
        menuDTO.setId(idWorker.nextId());

        // 生成menuDO
        MenuDO menuDO = new MenuDO();
        BeanUtils.copyProperties(menuDTO, menuDO);

        // 保存菜单
        menuDAO.save(menuDO);

        return menuDTO;
    }

    /**
     * 更新菜单，更新菜单的同时根据菜单编码更新Redis缓存中的菜单信息
     * @param menuDTO
     * @return
     * @throws BizException
     */
    @CachePut(cacheNames = "sys_menu", key = "#menuDTO.code")
    @Override
    public MenuDTO update(MenuDTO menuDTO) throws BizException {
        if (menuDTO == null) {
            return null;
        }

        // 生成menuDO
        MenuDO menuDO = menuDAO.findByCode(menuDTO.getCode());
        if (menuDO == null) {
            return null;
        }

        // TODO 有BUG，会将menuDTO中null字符赋给menuDO，导致更新异常
        BeanUtils.copyProperties(menuDTO, menuDO, "id");

        // 更新菜单
        menuDAO.save(menuDO);

        return menuDTO;
    }

    /**
     * 根据菜单编码删除菜单，同时删除缓存中的菜单
     * @param code
     * @return
     * @throws BizException
     */
    @CacheEvict(cacheNames = "sys_menu", key = "#code")
    @Transactional // jpa deleteByXXX方法如果不添加@Transactional注解会报错
    @Override
    public Integer deleteByCode(String code) throws BizException {
        if (StringUtils.isEmpty(code)) {
            return 0;
        }

        return menuDAO.deleteByCode(code);
    }

}
